<script lang='ts' setup>
import { onMounted, onUnmounted, reactive } from 'vue'
import { v2ray_get_state } from '@/apis/application/v2ray/v2ray_get_state.ts'
import { APPLICATION_STATE_INSTALLED, APPLICATION_STATE_INSTALLING, APPLICATION_STATE_RELOADING, APPLICATION_STATE_RESTARTING, APPLICATION_STATE_RUN_ERROR, APPLICATION_STATE_RUNNING, APPLICATION_STATE_STARTING, APPLICATION_STATE_STOPPED, APPLICATION_STATE_STOPPING, ApplicationState } from '@/apis/application/state.ts'
import { v2ray_install } from '@/apis/application/v2ray/v2ray_install.ts'
import { v2ray_start } from '@/apis/application/v2ray/v2ray_start.ts'
import { v2ray_stop } from '@/apis/application/v2ray/v2ray_stop.ts'
import { v2ray_restart } from '@/apis/application/v2ray/v2ray_restart.ts'
import { useRouter } from 'vue-router'
import { Api } from '@/apis/structs.ts'
import Application from '@/components/applications/Application.vue'

const router = useRouter()
const state = reactive<{ id: NodeJS.Timeout | undefined, loading: boolean, state: ApplicationState, installing: boolean, starting: boolean, restarting: boolean, stopping: boolean }>({
  id: undefined,
  loading: true,
  state: { state: 1, progress: 0, message: '', stage: '', stage_progress: 0, version: '' },
  installing: false,
  starting: false,
  restarting: false,
  stopping: false
})

onMounted(async () => {
  v2ray_get_state().then(async (response: Api<ApplicationState>) => {
    state.loading = false
    if (0 !== response.code) {
      window.$message.error(response.message)

      return
    }

    state.state = response.data
    if (undefined === state.id && (APPLICATION_STATE_INSTALLING === state.state.state || APPLICATION_STATE_STARTING === state.state.state || APPLICATION_STATE_RELOADING === state.state.state || APPLICATION_STATE_RESTARTING === state.state.state || APPLICATION_STATE_STOPPING === state.state.state)) {
      state.id = setTimeout(refresh_state, 1000)
    }
  })
})

onUnmounted(async () => {
  if (undefined !== state.id) {
    clearTimeout(state.id)
  }
})

async function install(): Promise<void> {
  if (APPLICATION_STATE_INSTALLING === state.state.state) {
    window.$message.warning('V2ray应用正在安装中')

    return
  }

  if (APPLICATION_STATE_STARTING === state.state.state || APPLICATION_STATE_RUNNING === state.state.state || APPLICATION_STATE_RESTARTING === state.state.state || APPLICATION_STATE_STOPPING === state.state.state) {
    window.$message.warning('V2ray应用当前状态不可执行安装操作')

    return
  }

  state.installing = true
  const response = await v2ray_install(true)
  state.installing = false

  if (0 !== response.code) {
    window.$message.error(response.message)

    return
  }

  window.$message.success('V2ray应用开始安装')
  await refresh_state()
}

async function refresh_state(): Promise<void> {
  const response = await v2ray_get_state()
  if (0 === response.code) {
    state.state = response.data

    if (APPLICATION_STATE_INSTALLING === state.state.state || APPLICATION_STATE_STARTING === state.state.state || APPLICATION_STATE_RESTARTING === state.state.state || APPLICATION_STATE_RELOADING === state.state.state || APPLICATION_STATE_STOPPING === state.state.state) {
      state.id = setTimeout(refresh_state, 1000)
    }
  }
}

async function start(): Promise<void> {
  if (APPLICATION_STATE_INSTALLED !== state.state.state && APPLICATION_STATE_RUN_ERROR !== state.state.state && APPLICATION_STATE_STOPPED != state.state.state) {
    window.$message.warning('V2ray应用当前状态不可启动')

    return
  }

  state.starting = true
  const response = await v2ray_start()
  state.starting = false

  if (0 !== response.code) {
    window.$message.error(response.message)

    return
  }

  window.$message.success('V2ray应用正在启动')
  await refresh_state()
}

async function restart(): Promise<void> {
  if (APPLICATION_STATE_RUNNING !== state.state.state) {
    window.$message.warning('V2ray应用当前状态不可重启')

    return
  }

  state.restarting = true
  const response = await v2ray_restart()
  state.restarting = false

  if (0 !== response.code) {
    window.$message.error(response.message)

    return
  }

  window.$message.success('V2ray应用正在重启')
  await refresh_state()
}

async function stop(): Promise<void> {
  if (APPLICATION_STATE_RUNNING !== state.state.state) {
    window.$message.warning('V2ray应用当前状态不可停止')

    return
  }

  state.stopping = true
  const response = await v2ray_stop()
  state.stopping = false

  if (0 !== response.code) {
    window.$message.error(response.message)

    return
  }

  window.$message.success('V2ray应用正在停止')
  await refresh_state()
}

async function open(): Promise<void> {
  window.open("https://github.com/v2fly/v2ray-core")
}
</script>

<template>
  <Application :installing='state.installing' :loading='state.loading' :restarting='state.restarting' :starting='state.starting' :state='state.state' :stopping='state.stopping' @configuration='router.push({name: "application-v2ray-configuration"})' @install='install' @restart='restart' @start='start' @stop='stop'>
    <template v-slot:title>
      <span class='link' @click='open'>V2ray</span>
    </template>
    <template v-slot:description>
      <span>V2ray是由Project V组织打造的一个代理工具，该工具支持多种形式的连接协议。通过不同协议的组合可以适用于多种多样的场景</span>
    </template>
  </Application>
</template>

<style scoped>

</style>
